<template>
    <div class="full-h flex-center" id="xpAppStore" @mousedown.stop="" style="position:relative;" v-if="!reloadLoading&&!errorVisible">
        <div class="xp-store-left full-h">
            <div class="xp-store-menu">
                <div class="scrollbar full-h" style="overflow-y: auto;">
                    <template v-if="isExpand">
                        <div v-for="item in navList" :key="item.index"
                        @click="handleToggleMenu(item)"
                        :class="currentPage.index === item.index?'xp-menu-item-active':''"
                        class="flex-start xp-menu-item" style="font-size:14px">
                            <component :is="item.icon" style="width: 14px;height: 14px;"></component>
                            <p class="oneline">{{item.name}}</p>
                        </div>
                    </template>
                    <template v-else>
                        <div v-for="item in navList" :key="item.index"
                        @click="handleToggleMenu(item)"
                        :class="currentPage.index === item.index?'xp-menu-item-active':''"
                        class="flex-start xp-menu-item">
                            <el-tooltip
                            effect="dark"
                            :content="item.name"
                            placement="right">
                                <component :is="item.icon" style="width: 16px;height: 16px;"></component>
                            </el-tooltip>
                        </div>
                    </template>
                </div>
            </div>
        </div>
        <div class="xp-store-right full-h">
            <div class="xp-store-container flex-column-start" v-show="currentPage.index !== '3'">
                <div class="xp-store-top-content flex-start flex-warp" style="margin-left: 4px;">
                    <el-input v-model="searchValue" placeholder="搜索" clearable 
                    style="width:200px;margin: 0 10px 0 0;padding-bottom: 10px;" @keyup.enter="handleSearch">
                        <template #prefix>
                            <el-icon class="el-input__icon"><search /></el-icon>
                        </template>
                    </el-input>
                    <div class="flex-center" style="padding-bottom: 10px;">
                        <el-select v-model="grouping" placeholder="选择分组" clearable style="width:200px">
                            <el-option
                            v-for="item in appStore.getFolderData"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value"
                            />
                        </el-select>
                    </div>
                </div>
                <div class="xp-store-tag flex-start flex-warp">
                    <span v-for="item in appTag" 
                    :key="item"
                    :class="currentPage.tag === item?'xp-store-tag-active':''"
                    @click="handleToggleTag(item)">{{item}}</span>
                </div>
                <div class="scrollbar full-layout xp-store-content" @scroll="handleScroll">
                    <ul v-if="!loading&&!stateVisible" :infinite-scroll-disabled="noMore" v-infinite-scroll="loadMoreData">
                        <li 
                        class="xp-store-app flex-column-start" 
                        v-for="item in searchData.length?searchData:appList" :key="item.id">
                            <div class="flex-start">
                                <img :src="CheckFullUrl(item.icon)"
                                @click="handleOutOpen(item)"
                                :class="item.type!=='slot'?'pointer':''"
                                :style="{backgroundColor:item.background}">
                                <p class="oneline" style="margin-left:10px">{{item.name}}</p>
                            </div>
                            <div>
                                <p class="twoline xp-store-appInfo" :title="item.intro">{{item.intro}}</p>
                            </div>
                            <div class="flex-end full-w">
                                <el-button 
                                style="margin-right:10px"
                                round 
                                :disabled="isAddApp(item.id)"
                                @click="handleAdd(item)"
                                size="small">
                                {{isAddApp(item.id) ? '已添加' : '添加'}}
                                </el-button>
                            </div>
                        </li>
                    </ul>
                    <div class="text-info">—— {{moreLoading?'正在加载更多':'暂无更多'}} ——</div>
                    <div class="list-box-loading flex-center" v-if="loading">
                        <div class="spinner"></div>
                    </div>
                    <div class="full-h flex-center" v-if="!loading&&stateVisible">
                        <el-empty 
                        :image="stateImg"
                        :description="stateText">
                        </el-empty>
                    </div>
                </div>
            </div>
            <div v-if="currentPage.index === '3'" class="full-layout" style="padding: 20px;">
                <p style="font-size: 20px; margin-bottom: 20px; font-weight: 600;"># 使用须知</p>
                <div style="font-size:14px">
                    · 应用内的资源均收集自互联网，平台仅提供方便的快捷打开功能，如有侵权请联系作者进行下架
                </div>
                <div style="font-size:14px">
                    · 应用分为外应用和内应用，外应用只支持外部标签页打开网页，内应用分为内嵌的网页和内嵌的组件
                </div>
                <div style="font-size:14px">
                    · 灵动组件是专门适配了灵动岛的应用，支持在灵动岛上显示
                </div>
                <br/>
                <br/>
                <br/>
                <p style="font-size: 20px; margin-bottom: 20px; font-weight: 600;"># 联系</p>
                <div style="color:#808080;font-size: 14px;">
                    邮箱：2783335126@qq.com
                </div>
            </div>
        </div>
    </div>
    <div class="full-h flex-center" v-if="reloadLoading">
        <div class="spinner"></div>
    </div>
    <div class="full-h flex-center" v-if="!reloadLoading&&errorVisible">
        <el-empty 
        :image="require('@/assets/error.png')"
        description="商店异常">
        </el-empty>
    </div>

</template>

<script lang='ts'>
import { reactive, toRefs, getCurrentInstance, onMounted, onBeforeUnmount, computed, watchEffect, nextTick } from 'vue';
import useCheck from '@/hooks/useCheck';
import { useAppStore } from '@/store/app';
export default {
    name:'xpAppStore',
    props: {

    },
    components: {

    },
    emits:[],
    setup (props, context) 
    {
        const appStore = useAppStore();
        const { proxy }:any = getCurrentInstance();
        let data = reactive({
            appTag:[] as string[],
            stateImg:require('@/assets/empty.png'),
            stateText:'空空如也',
            stateVisible:false,
            loading:true,
            reloadLoading:true,
            errorVisible:false,
            isExpand:true,
            timer:null as any,
            grouping:'',
            searchValue:'',
            currentPage:{
                index:'0',
                tag:'全部'
            },
            searchData:[] as any,
            navList:[
                {
                    icon:'Link',
                    name:'外应用',
                    index:'0',
                    tag:'全部',
                    type:['web'],
                    data:{}
                },
                {
                    icon:'Compass',
                    name:'内应用',
                    index:'1',
                    tag:'全部',
                    type:['iframe', 'slot'],
                    data:{}
                },
                {
                    icon:'Notification',
                    name:'灵动组件',
                    index:'2',
                    tag:'全部',
                    type:'island',
                    data:{}
                },
                {
                    icon:'Warning',
                    name:'关于',
                    index:'3'
                }
            ] as any,
            dataSource:[] as any,
            appList:[] as any,
            timer1:null as any,
            noMore:false,
            moreLoading:false
        });
        let methods = {
            handleScrollHeight ()
            {
                nextTick(() => 
                {
                    let element = document.querySelector('.xp-store-content') as HTMLDivElement;
                    let index = Number(data.currentPage.index);
                    element.scrollTop = data.navList[index].data[data.currentPage.tag].scrollHeight; 
                });
            },
            handleError ()
            {
                data.loading = false;
                data.stateVisible = true;
                data.stateImg = require('@/assets/error.png');
                data.stateText = '加载失败';
            },
            handleEmpty ()
            {
                data.loading = false;
                data.stateVisible = true;
                data.stateImg = require('@/assets/empty.png');
                data.stateText = '空空如也';
            },
            handleResize ()
            {
                let element:any = document.querySelector('#xpAppStore');
                let leftNav:any = document.querySelector('.xp-store-left');   
                const observer = new ResizeObserver((entries) => 
                {
                    const con = entries[0];
                    const { width, height } = con.contentRect;
                    if (width <= 700)
                    {
                        data.isExpand = false;
                        leftNav.style.width = 70 + 'px';
                    }
                    else
                    {
                        data.isExpand = true;
                        leftNav.style.width = 150 + 'px';
                    }
                });
                observer.observe(element); 
                // data.timer = setInterval(() => 
                // {
                //     let width = element.offsetWidth;
                //     if (width <= 700)
                //     {
                //         data.isExpand = false;
                //         leftNav.style.width = 70 + 'px';
                //     }
                //     else
                //     {
                //         data.isExpand = true;
                //         leftNav.style.width = 150 + 'px';
                //     }
                // }, 1000);
            },
            handleToggleMenu (value)
            {
                data.currentPage.index = value.index;
                if (value.index !== '3')
                {
                    data.currentPage.tag = value.tag;
                    methods.handleToggleTag(value.tag);
                }
            },
            async handleToggleTag (value)
            {
                data.noMore = false;
                data.loading = true;
                data.stateVisible = false;
                let index = Number(data.currentPage.index);
                data.currentPage.tag = value;
                data.navList[index].tag = value;
                let currentData = data.navList[index];
                if (currentData?.data[value])
                {
                    data.appList = currentData?.data[value]['data'];
                    data.loading = false;
                    if (!data.appList.length)
                    {
                        methods.handleEmpty();
                    }
                    else
                    {
                        methods.handleScrollHeight();
                    }
                    return;
                }
                if (value === '全部')
                {
                    data.appList = methods.getAppData();
                    data.loading = false;
                    if (!data.appList.length)
                    {
                        methods.handleEmpty();
                    }
                    else
                    {
                        methods.handleScrollHeight();
                    }
                    return;
                }
                // 走接口获取
                let query = {
                    type:currentData.type,
                    tag:value
                };
                try
                {
                    const res = await proxy.$http.app.getAppDataByTag(query);
                    data.navList[index].data[value] = {
                        data:res.data.content,
                        scrollHeight:0,
                        page:1
                    };
                    data.appList = res.data.content;
                    if (!data.appList.length)
                    {
                        methods.handleEmpty();
                    }
                    
                }
                catch (err)
                {
                    console.error('获取失败' + err);
                    methods.handleError();
                }
                data.loading = false;
            },
            async findAppData ()
            {
                try
                {
                    const res1 = await proxy.$http.app.getAppTags();
                    const res2 = await proxy.$http.app.getAppData();
                    data.appTag = res1.data.content;
                    data.dataSource = res2.data.content;
                    data.appList = methods.getAppData();
                    data.reloadLoading = false;
                    data.loading = false;
                    if (!data.appList.length)
                    {
                        data.stateVisible = true;
                    }
                    // nextTick(() => 
                    // {
                    //     methods.handleResize();
                    // });
                }
                catch (err)
                {
                    data.reloadLoading = false;
                    data.errorVisible = true;
                }
            },
            getAppData ()
            {
                let appList = [] as any;
                let currentIndex = Number(data.currentPage.index);
                if (currentIndex >= 3) return appList;
                let currentTag = data.currentPage.tag;
                let currentData:any = data.navList[currentIndex];
                let currentType = currentData.type;
                if (currentData?.data[currentTag] && currentData?.data[currentTag]['data'].length)
                {
                    appList = currentData?.data[currentTag]['data'];
                }
                else
                {
                    if (!data.dataSource.length) return appList;
                    if (currentType === 'island')
                    {
                        appList = data.dataSource.filter((item) => 
                        {
                            if (currentTag === '全部')
                            {
                                return item['isIsland'] === true;
                            }
                            return item['isIsland'] === true && item.tag.includes(currentTag);
                        });
                        data.navList[currentIndex]['data'][currentTag] = {
                            data:appList,
                            scrollHeight:0,
                            page:1
                        };
                        console.log(data.dataSource, appList);
                        
                        return appList;
                    }
                    appList = data.dataSource.filter((item) => 
                    {
                        if (currentTag === '全部')
                        {
                            return currentType.includes(item.type);
                        }
                        return currentType.includes(item.type) && item.tag.includes(currentTag);
                    });
                    data.navList[currentIndex]['data'][currentTag] = {
                        data:appList,
                        scrollHeight:0,
                        page:1
                    };
                }
                return appList;
            },
            async handleSearch ()
            {
                if (data.searchValue.trim() === '') return;
                data.loading = true;
                data.stateVisible = false;
                let index = Number(data.currentPage.index);
                data.currentPage.tag = '全部';
                data.navList[index].tag = '全部';
                try 
                {
                    let query = {
                        type:data.navList[index].type,
                        searchValue:data.searchValue
                    };
                    const res = await proxy.$http.app.searchAppData(query);
                    if (!res.data.content.length)
                    {
                        methods.handleEmpty();
                        return;
                    }
                    data.searchData = res.data.content;
                }
                catch (err)
                {
                    methods.handleError();
                }
                data.loading = false;
            },
            handleOutOpen (item)
            {
                if (item.type !== 'slot')
                {
                    return window.open(item.link, '_blank');
                }
            },
            handleAdd (item)
            {
                if (isAddApp.value(item.id)) return;
                appStore.addApp(item, data.grouping);
            },
            handleScroll (e)
            {
                data.timer1 && clearTimeout(data.timer1);
                data.timer1 = setTimeout(() => 
                {
                    let scrollHeight = e.srcElement.scrollTop;
                    let currentIndex = Number(data.currentPage.index);
                    data.navList[currentIndex].data[data.currentPage.tag].scrollHeight = scrollHeight;
                }, 100);
            },
            async loadMoreData ()
            {
                // 加载更多
                if (data.noMore) return;
                if (data.moreLoading) return;
                data.moreLoading = true;
                let index = Number(data.currentPage.index);
                let currentData = data.navList[index];
                // let page = currentData.data[data.currentPage.tag].page;
                data.navList[index].data[data.currentPage.tag].page += 1;
                let query = {
                    type:currentData.type,
                    tag:data.currentPage.tag,
                    skip:currentData.data[data.currentPage.tag].data.length
                };
                try
                {
                    const res = await proxy.$http.app.getAppDataByPage(query);
                    data.moreLoading = false;
                    if (!res.data.content.length)
                    {
                        data.noMore = true;
                        return;
                    }
                    data.navList[index].data[data.currentPage.tag].data.push(...res.data.content);
                    data.appList = methods.getAppData();
                    methods.handleScrollHeight();
                }
                catch (err)
                {
                    data.moreLoading = false;
                }
            }
        };

        watchEffect(() => 
        {
            if (data.searchValue.trim() === '')
            {
                data.searchData = [];
                data.appList = methods.getAppData();
            }
        });

        const isAddApp = computed(() =>
        {
            return function (id)
            {
                let ids = [] as any;
                appStore.appData.forEach((item) => 
                {
                    if (item.children)
                    {
                        item.children.forEach((i) => ids.push(i.id));
                    }
                    ids.push(item.id);
                });
                return ids.includes(id);
            };
        });
        onMounted(async () => 
        {
            await methods.findAppData();
            methods.handleResize();
        });

        onBeforeUnmount(() => 
        {
            clearInterval(data.timer);
        });
        return { 
            ...toRefs(data),
            ...methods,
            appStore,
            isAddApp,
            ...useCheck()
        };
    }
};
</script>

<style scoped lang="scss">
#xpAppStore {
    min-width: 260px;
}
.xp-store-left {
    width: 150px;
    padding: 10px 5px 10px 10px;
    min-width: 70px;
    max-width: 150px;
    transition: all .3s;
}

.xp-store-right {
    flex: 4;
    padding: 10px 10px 10px 5px;
}

.xp-store-menu {
    height: 100%;
    border-radius: 10px;
    background-color: var(--el-bg-color-tool);
    padding: 5px 5px;
    // overflow-y: auto;

    .xp-menu-item {
        margin: 5px 5px;
        padding: 10px;
        border-radius: 10px;
        transition: all .2s;
        // width: calc(100% - 20px);
        cursor: pointer;

        &:hover {
            background-color: var(--el-bg-color-folder);
        }
    }

    .xp-menu-item-active {
        background-color: var(--el-bg-color-folder);
    }

    p {
        margin-left: 10px;
    }
}

.xp-store-container {
    width: 100%;
    height: 100%;
    position: relative;

    .xp-store-top-content {
        width: 100%;
    }
    .xp-store-tag {
        width: 100%;

        span {
            cursor: pointer;
            font-size: 12px;
            margin: 2px 3px;
            padding: 3px 6px;
            border-radius: 20px;
            background-color: var(--el-bg-color-tool);
        }

        .xp-store-tag-active {
            background-color: var(--el-color-primary);
            color:#fff;
        }

    }

    .xp-store-content {
        // height: calc(100% - 60px);
        margin-top:5px;
        overflow-y: auto;

        ul {
            // height: 100%;
            width: 100%;
            display: grid;
            grid-template-columns: repeat(auto-fill, 269px);
            grid-template-rows: repeat(auto-fill,145px);
            justify-content: start;
            grid-auto-flow: dense;

            .xp-store-app {
                min-width: 250px;
                margin: 5px;
                background-color: var(--el-bg-color-tool);
                border-radius: 10px;
                padding: 5px;

                div {
                    margin: 5px;
                }

                img {
                    width: 40px;
                    height: 40px;
                    border-radius: 10px;
                    // cursor: pointer;
                }

                p {
                    font-size: 14px;
                }

                .xp-store-appInfo {
                    color: #808080;
                    min-height: 32px;
                    font-size: 12px;
                }
            }
        }
    }
}
</style>
